/**
 *  This file is part of MunchLevel.
 *
 *  MunchLevel is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MunchLevel is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MunchLevel.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.munchlevel.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.munchlevel.R;

public class PercentageLayout extends RelativeLayout {

	// helper vars for onlayout
	private Rect childRect = new Rect();
	private Rect childGravityRect = new Rect();

	public PercentageLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public PercentageLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public PercentageLayout(Context context) {
		super(context);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

		int containerWidth = MeasureSpec.getSize(widthMeasureSpec);
		int containerHeight = MeasureSpec.getSize(heightMeasureSpec);

		if (containerWidth == 0) {
			// use 480/800 aspect ration if width is unknown and we have to
			// scroll
			containerWidth = (int) (containerHeight * 0.66F);

			widthMeasureSpec = MeasureSpec.makeMeasureSpec(containerWidth, MeasureSpec.EXACTLY);
			setMeasuredDimension(containerWidth, containerHeight);
		}

		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		final int count = getChildCount();

		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);

			LayoutParams lp = (LayoutParams) child.getLayoutParams();

			if (lp.hasPercentageLayout()) {
				int childWidth = -1;
				int childHeight = -1;

				if (lp.getLeftPercentage() != -1 && lp.getRightPercentage() != -1) {
					childWidth = (int) (containerWidth * (lp.getRightPercentage() - lp.getLeftPercentage()) / 100);
				}

				if (lp.getTopPercentage() != -1 && lp.getBottomPercentage() != -1) {
					childHeight = (int) (containerHeight * (lp.getBottomPercentage() - lp.getTopPercentage()) / 100);
				}

				int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
				int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
				if (childWidth > 0) {
					childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
				}
				if (childHeight > 0) {
					childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST);
				}

				// Debug.verbose("measer of child " + childWidth + "/" +
				// childHeight);

				child.measure(childWidthSpec, childHeightSpec);

			}
		}

	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		super.onLayout(changed, left, top, right, bottom);

		final int count = getChildCount();

		final int containerWidth = right - left;
		final int containerHeight = bottom - top;

		for (int i = 0; i < count; i++) {
			final View child = getChildAt(i);
			if (child.getVisibility() != GONE) {
				LayoutParams lp = (LayoutParams) child.getLayoutParams();

				if (lp.hasPercentageLayout()) {

					// Debug.verbose("layout of child " + child.getWidth() + "/"
					// + child.getHeight());
					// Debug.verbose("layout of child mes:" +
					// child.getMeasuredWidth() + "/" +
					// child.getMeasuredHeight());
					int childBottom = child.getBottom();
					int childTop = child.getTop();
					int childLeft = child.getLeft();
					int childRight = child.getRight();

					if (lp.getLeftPercentage() != -1) {
						childLeft = (int) (containerWidth * lp.getLeftPercentage() / 100);
					}

					if (lp.getRightPercentage() != -1) {
						childRight = (int) (containerWidth * lp.getRightPercentage() / 100);
					}
					if (lp.getTopPercentage() != -1) {
						childTop = (int) (containerHeight * lp.getTopPercentage() / 100);
					}
					if (lp.getBottomPercentage() != -1) {
						childBottom = (int) (containerHeight * lp.getBottomPercentage() / 100);
					}

					childRect.set(childLeft, childTop, childRight, childBottom);
					Gravity.apply(lp.gravity, child.getMeasuredWidth(), child.getMeasuredHeight(), childRect,
							childGravityRect);
					child.layout(childGravityRect.left, childGravityRect.top, childGravityRect.right,
							childGravityRect.bottom);
				}
			}

		}

	}

	@Override
	public LayoutParams generateLayoutParams(AttributeSet attrs) {
		return new PercentageLayout.LayoutParams(getContext(), attrs);
	}

	@Override
	protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
		return p instanceof LayoutParams;
	}

	@Override
	protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
		return new PercentageLayout.LayoutParams(p);
	}

	public class LayoutParams extends RelativeLayout.LayoutParams {

		private int leftPercentage = -1, rightPercentage = -1, topPercentage = -1, bottomPercentage = -1;

		private boolean aspectRatio = false;

		private int gravity;

		public LayoutParams(Context context, AttributeSet attrs) {
			super(context, attrs);

			TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PercentageLayout_Layout);

			leftPercentage = a.getInt(R.styleable.PercentageLayout_Layout_layout_leftPercentage, -1);
			rightPercentage = a.getInt(R.styleable.PercentageLayout_Layout_layout_rightPercentage, -1);
			topPercentage = a.getInt(R.styleable.PercentageLayout_Layout_layout_topPercentage, -1);
			bottomPercentage = a.getInt(R.styleable.PercentageLayout_Layout_layout_bottomPercentage, -1);

			aspectRatio = a.getBoolean(R.styleable.PercentageLayout_Layout_layout_aspectRatio, false);

			gravity = a.getInt(R.styleable.PercentageLayout_Layout_android_layout_gravity, Gravity.CENTER);
			a.recycle();
		}

		public LayoutParams(int width, int height) {
			super(width, height);

		}

		public LayoutParams(android.view.ViewGroup.LayoutParams params) {
			super(params);
		}

		public LayoutParams(MarginLayoutParams params) {
			super(params);
		}

		public int getLeftPercentage() {
			return leftPercentage;
		}

		public void setLeftPercentage(int leftPercentage) {
			this.leftPercentage = leftPercentage;
		}

		public int getRightPercentage() {
			return rightPercentage;
		}

		public void setRightPercentage(int rightPercentage) {
			this.rightPercentage = rightPercentage;
		}

		public int getTopPercentage() {
			return topPercentage;
		}

		public void setTopPercentage(int topPercentage) {
			this.topPercentage = topPercentage;
		}

		public int getBottomPercentage() {
			return bottomPercentage;
		}

		public void setBottomPercentage(int bottomPercentage) {
			this.bottomPercentage = bottomPercentage;
		}

		public boolean isAspectRatio() {
			return aspectRatio;
		}

		public void setAspectRation(boolean aspectRation) {
			this.aspectRatio = aspectRation;
		}

		public boolean hasPercentageLayout() {
			return leftPercentage != -1 || rightPercentage != -1 || topPercentage != -1 || bottomPercentage != -1;
		}

		public int getGravity() {
			return gravity;
		}

		public void setGravity(int gravity) {
			this.gravity = gravity;
		}

		public void setAspectRatio(boolean aspectRatio) {
			this.aspectRatio = aspectRatio;
		}

	}

}
